using System.Text.RegularExpressions;

namespace PhpDocBlockGenerator.Model.Php
{
    public static class PhpRegex
    {
        //NOTE: the .NET-Regex-Class is thread-safe -> no need to lock the objects

        //doc block regex
        public static Regex RegDeleteSpecialChars = new Regex(@"\n[\s\t]*\*|[\s\t]*(/\*\*|\*/\s\n)", RegexOptions.Compiled);
        public static Regex RegDeleteNeedlessLinebreaks = new Regex(@"^[\s\t]*\n|\n[\s\t]*$", RegexOptions.Compiled);
        public static Regex RegSearchDescription = new Regex(@"^[^@]*", RegexOptions.Compiled);
        public static Regex RegSearchEmailAdress = new Regex(@"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b", RegexOptions.Compiled|RegexOptions.IgnoreCase);
        public static Regex RegSearchAtSign = new Regex(@"(?<=@)[^@]*", RegexOptions.Compiled);
        public static Regex RegSearchEmailPlaceholder = new Regex(@"(?<=\<\[E-Mail\])\d{1,2}(?=\>)", RegexOptions.Compiled);

        //doc block object / property
        public static Regex RegSearchFirstWordForType = new Regex(@"[^\s\t]*", RegexOptions.Compiled);
        public static Regex RegSearchAfterFirstWordForDesc = new Regex(@"[\s\t][^\*/]*", RegexOptions.Compiled);
        public static Regex RegSearchWords = new Regex(@"[\w_\$\\][^\s\t]*", RegexOptions.Compiled);
        public static Regex RegSearchVarName = new Regex(@"\$[\w\d_]*", RegexOptions.Compiled);
        public static Regex RegSearchExceptionName = new Regex(@"[\w_\d]*Exception[\w_\d]*", RegexOptions.Compiled);

        //class
        public static Regex RegSearchPropertyName = new Regex(@"(?<=^[\s\t]*(public|protected|private|static)[\s\t]*(public|protected|private|static|)[\s\t]*)\$[^\;\=\s\t]*", RegexOptions.Compiled);
        public static Regex RegSearchMethodName = new Regex(@"(?<=^[\s\t]*(public|protected|private|static|abstract|)[\s\t]*(public|protected|private|static|abstract|)[\s\t]*(public|protected|private|static|abstract|)[\s\t]*function)[^\(]*", RegexOptions.Compiled);

        //file
        public static Regex RegSearchPropAuthorOrVersion = new Regex(@"@version|@author\s*Unister", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchClassName = new Regex(@"(?<=^[\s\t]*(abstract[\s\t]*|final[\s\t]*|)(class|interface)[\s\t])[\w\d_]*", RegexOptions.Compiled);
        public static Regex RegSearchClosingCurlyBrace = new Regex(@"[\s\t]*\}[\s\t]*", RegexOptions.Compiled);
        
        //method or property
        public static Regex RegSearchAbstractMethod = new Regex(@"function\s*[\w\s]*\(.*\)\s*;", RegexOptions.Compiled);
        public static Regex RegSearchThis = new Regex(@"^[\s\t]*\$this[\s\t]*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchInt = new Regex(@"[\s\t]*\d+[\s\t]*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchFloat = new Regex(@"[\s\t]*\d+\.\d+[\s\t]*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchBoolean = new Regex(@"[\s\t]*(tru|fals)e[\s\t]*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchString = new Regex("[\\s\\t]*(\".*\"|'.*')[\\s\\t]*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchArray = new Regex(@"array\(", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchNull = new Regex(@"^[\s\t]*null[\s\t]*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchNew = new Regex(@"(?<=[\s\t]*new[\s\t]+)([\w\d\\])*[^\(]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static Regex RegSearchOpeningCurlyBraceOrSemicolon = new Regex(@"[\{;]", RegexOptions.Compiled);
        public static Regex RegSearchParamsAsBlock = new Regex(@"([^\,\(]*)\$([^\,\=\)\s\t]*)", RegexOptions.Compiled);
        public static Regex RegSearchParamTypeAndName = new Regex(@"[^\s]+", RegexOptions.Compiled);
        public static Regex RegSearchPropReturn = new Regex(@"(?<=[^@]return )([^\;]*)", RegexOptions.Compiled);
        public static Regex RegSearchThrowNew = new Regex(@"(?<=[^@]throw new )([^\(]*)", RegexOptions.Compiled);
        public static Regex RegSearchIndent = new Regex(@"^[\s\t]*", RegexOptions.Compiled);
        public static Regex RegSearchAssignment = new Regex(@"\=", RegexOptions.Compiled);

        // misc things
        public static Regex RegSearchEndOfDocBlock = new Regex(@"^.*\*/[\s\t]*$", RegexOptions.Compiled);
        public static Regex RegSearchEndOfPreviousLogic = new Regex(@"(\{|\}|\;)$", RegexOptions.Compiled);
        public static Regex RegSearchBeginOfDocBlock = new Regex(@"^[\s\t]*/\*\*.*$", RegexOptions.Compiled);
        public static Regex RegSearchBeginOfComment = new Regex(@"^[\s\t]*/\*.*$", RegexOptions.Compiled);
        public static Regex RegSearchLineBreaks = new Regex(@"\n", RegexOptions.Compiled);
        public static Regex RegSearchForAnyCharacter = new Regex(@"[\w\d]", RegexOptions.Compiled);
        public static Regex RegSearchForPhpStartTag = new Regex(@"\<\?(php|)", RegexOptions.Compiled);

        // indent
        public static Regex RegTabs = new Regex(@"\t", RegexOptions.Compiled);
        public static Regex RegObjectOperator = new Regex(@"-\>", RegexOptions.Compiled);
        public static Regex RegObjectOperatorAtBeginning = new Regex(@"^\s*-\>", RegexOptions.Compiled);
        public static Regex RegQuoteAtBeginning = new Regex("\\s*\\\"", RegexOptions.Compiled);

        //php.exe return
        public static Regex RegSearchPhpExeParseNoErrors = new Regex(@"^No syntax errors detected in .*", RegexOptions.Compiled);
    }
}
